#pragma once

class Shader
{
	friend class Program;
private:
	GLuint ID;
	int type;
	std::string filename;

public:
	static const int VERTEX_SHADER = 0;
	static const int FRAGMENT_SHADER = 1;

	Shader(const std::string & filename);
	Shader(const std::string & filename, int type);
	~Shader();

	int getShaderType();
};

class Program
{
private:
	static const int STATUS_UNLINKED = 0;
	static const int STATUS_FAIL_LINK = 1;
	static const int STATUS_LINKED_BUT_NOT_USED = 2;
	static const int STATUS_LINKED_AND_USED = 3;

	GLuint ID;
	int status = STATUS_UNLINKED;

public:
	Program();
	~Program();

	void attach(const Shader & shader);
	void attach(Shader * shader);
	bool link();
	void use();
	void unuse();

	void uniform1i(const std::string & name, int value);
	void uniform3f(const std::string & name, const glm::vec3 & value);
	void uniformmat4(const std::string & name, const glm::mat4 & value);
	void uniform1f(const std::string & name, float value);
	void uniform1b(const std::string & name, bool value);
	void uniform2f(const std::string & name, const glm::vec2 & value);
	void uniform2f(const std::string & name, float v1, float v2);
};